#! -*- coding: utf-8 -*-

"""
Baan xmlrpc server
"""

from SimpleXMLRPCServer import SimpleXMLRPCServer
import xmlrpclib
import baan_stpapi
import SocketServer



class BaanXMLRPCServer(SimpleXMLRPCServer):
    def __init__(self,addr=("", 8000),logRequests=False,multithread=False):
        SimpleXMLRPCServer.__init__(self,addr,logRequests=logRequests,allow_none=True)
        self.multithread = multithread
        #self.client = baan_stpapi.Baan(self.class_string)
        self.class_string_list = set()
        self.clients = []

    def register_instance(self,instance):
        SimpleXMLRPCServer.register_instance(self,instance)
        self.class_string_list.update(instance._get_class_string())

    def serve_forever(self):
        self.create_clients()
        try:
            SimpleXMLRPCServer.serve_forever(self)
        except:
            pass
        finally:
            self.close_all_clients()

    def shutdown(self):
        self.close_all_clients()
        SimpleXMLRPCServer.shutdown()

    def create_clients(self):
        #start one instane for each class string found
        for class_string in self.class_string_list:
            client = baan_stpapi.Baan(class_string,multithread=self.multithread)
            self.clients.append(client)

    def close_all_clients(self):
        SimpleXMLRPCServer.server_close(self)
        for client in self.clients:
            client.quit()
        self.clients = []

    def CreateDispatch(self):
        dispatch = BaanDispatch()
        dispatch.multithread = self.multithread
        return dispatch



class AsyncBaanXMLRPCServer(SocketServer.ThreadingMixIn,BaanXMLRPCServer):
    def __init__(self,addr=("", 8000),logRequests=False):
        BaanXMLRPCServer.__init__(self,addr,logRequests=logRequests,multithread=True)

class BaanDispatch(object):
    def __init__(self):
        self.funcs = {}
        self.multithread = False

    def _get_class_string(self):
        "return all used class string"
        lst = set()
        for func in self.funcs.values():
            lst.add(func.class_string)
        return lst

    def _listMethods(self):
        return dir(self)

    def _dispatch(self,method,params):
        methd = method.split('.',1)
        if len(methd) == 1:
            func = getattr(self,method)
            return func(*params)
        else:
            funcs = self.funcs.get(methd[0])
            return funcs._dispatch(methd[1],params)

    def test(self):
        return 'ok'

class BaanFunc(object):
    def __init__(self,class_string='Baan4.Application'):
        self.class_string = class_string
        self.multithread = False

    def _listMethods(self):
        return dir(self)

    def _connect(self):
        client = baan_stpapi.Baan(self.class_string,self.multithread)
        return client

    def _dispatch(self, method, params):
        if method[0] == '_':
            raise Exception('method "%s" is not supported' % method)
        func = getattr(self,method)
        client = self._connect()
        try:
            res = func(client,*params)
        finally:
            client.quit()
        return res

    def test(self,client):
        return client.get_company()

    def get_company(self,client,company_number):
        client.switch_to_company(company_number)
        return client.get_company()


if __name__ == '__main__':
    # Create server
    #server = BaanXMLRPCServer(logRequests=True)
    server = AsyncBaanXMLRPCServer(logRequests=True)
    a = server.CreateDispatch()
    a.funcs['baantest'] = BaanFunc()
    server.register_instance(a)
    server.register_introspection_functions()

    # Run the server's main loop
    print 'Lancement du serveur XML-RPC.'
    server.serve_forever()


